package com.code.monitor.handler;

import com.code.monitor.message.HeartBeatMessage;
import com.code.monitor.message.Message;
import com.code.monitor.model.CacheManager;
import com.code.monitor.model.ServiceInfo;
import com.code.monitor.utils.PushMessageUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Date;

/**
 * @author ggh
 * @date 2023/5/8
 */
@ChannelHandler.Sharable
public class MessageHandler extends SimpleChannelInboundHandler<Message> {
    private static final Logger logger = LoggerFactory.getLogger(MessageHandler.class);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Message msg) throws Exception {
        SocketChannel key = (SocketChannel) ctx.channel();

        if (msg instanceof HeartBeatMessage) {
            HeartBeatMessage heartBeatMessage = (HeartBeatMessage) msg;
            String ip = heartBeatMessage.getIp();
            if (!CacheManager.existKey(key)) {
                logger.info("{}首次连接,发送上线消息", heartBeatMessage.getIp());

                ServiceInfo serviceInfo = new ServiceInfo();

                serviceInfo.setServiceName(heartBeatMessage.getServiceName());
                serviceInfo.setIp(heartBeatMessage.getIp());
                serviceInfo.setOnlineTime(new Date());
                serviceInfo.setOperationSystem(heartBeatMessage.getOperationSystem());
                InetSocketAddress inetAddress = (InetSocketAddress) ctx.channel().remoteAddress();
                serviceInfo.setPort(inetAddress.getPort());
                serviceInfo.setUuid(String.valueOf(ctx.handler().hashCode()));

                CacheManager.setServiceInfo(key, serviceInfo);

                // 为建立连接的socket添加活性检测
                ctx.pipeline().addBefore(ctx.name(), "idleStatusHandler", new IdleStateHandler(300, 0, 0));
                ctx.pipeline().addBefore(ctx.name(), "readIdleHandler", new ReadIdleHandler());

                PushMessageUtil.pushMessageToAllSubscriber();
            }
        } else {
            logger.info("其他消息，不做处理");
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        if (CacheManager.existKey((SocketChannel) ctx.channel())) {
            ServiceInfo serviceInfo = CacheManager.delServiceInfo((SocketChannel) ctx.channel());
            logger.info("{}:连接已断开", serviceInfo.getIp());
            PushMessageUtil.pushMessageToAllSubscriber();
            return;
        }

        super.channelInactive(ctx);
    }
}
